#include "TcpServer.hpp"
#include "HttpProtocol.hpp"
#include <memory>
#include <unordered_map>
#include <functional>

using handler_t = function<void(HttpRequest&,HttpResponse&)>;
class HttpServer
{
public:
    HttpServer(int port)
        : _tcpServerPtr(make_unique<TcpServer>(port))
    {
    }

    void Start()
    {
        _tcpServerPtr->InitTcpServer([this](SockPtr sockfd, InetAddr client)
                                     { return this->HttpHandleReq(sockfd, client); }); // 给tcpServer设置处理方法

        _tcpServerPtr->Loop(); // 开启Tcp
    }

    void Register(string funcname,handler_t func)
    {
        _router[funcname] = func;
    }

    // 这里，就是我们处理http的入口
    bool HttpHandleReq(SockPtr sockfd, InetAddr client)
    {
        LOG(LogGrade::NORMAL) << "HttpServer get a new sockfd," << sockfd->GetSockfd() << " client Info:" << client.getInfo();

        // 1. 获取请求
        string http_request;
        sockfd->Recv(&http_request);
        cout << "-------请求:\n" << http_request << endl;
        /*
            demo2:使用标准协议处理
        */
        // 2. 读取请求，对请求进行分析处理
        HttpRequest httpreq;
        httpreq.Deserialize(http_request);
        // cout << "用户想要："<< httpreq.Geturi() << endl;
        // 3. 请求处理完毕，构建应答
        HttpResponse httpresp;
        // 请求应该被分为两类    1. 请求静态资源 2. 提交参数，携带参数，需要进行交互
        if (httpreq.HasArgs())
        {
            //  /login?username=zhang&password=123456
            string path = httpreq.getPath(); // 获取带参的请求路径  
            if (safeCheck(path))
            {
                _router[path](httpreq,httpresp);    // /login?
            }
            else
            {
                httpresp.Build(httpreq);    //404
            }
        }
        else
        {
            // 没有参数，请求静态资源，可直接构建响应
            httpresp.Build(httpreq);
        }
        string resp;
        // 4.序列化应答
        httpresp.Serialize(&resp);
        cout << "-------------响应--------------" << endl;
        cout << resp << endl;
        cout << "-------------------------------" << endl;
        // 5. 发送
        sockfd->Send(resp);
        return true;

        /*
            demo1：写一个固定的处理方法
        */
        // string status_line = "Http/1.1 200 OK" + Sep + Blank_line;
        // string body = "hello world";
        // string http_response = status_line + body;
        // sockfd->Send(http_response);
        // return true;
    }

    bool safeCheck(string& path)
    {
        auto pos = _router.find(path);  //查找是否注册了该方法
        return pos != _router.end();
    }

    ~HttpServer()
    {
    }

private:
    unique_ptr<TcpServer> _tcpServerPtr;
    unordered_map<string,handler_t> _router;
};
